import Dep from "./observe/dep"
import Watcher from "./observe/watcher"

// 实现computed
export function initComputed(vm) {
  let watchers = (vm._computedWatchers = {})
  let computed = vm.$options.computed
  for (let key in computed) {
    // userDef 就是computed 里面的属性
    let userDef = computed[key]
    let getter = typeof userDef === "function" ? userDef : userDef.get
    let setter = userDef.set || (() => {})

    // 生成渲染 watcher
    watchers[key] = new Watcher(vm, getter, { lazy: true })
    defineComputed(vm, key, getter, setter)
  }
}

function defineComputed(target, key, getter, setter) {
  Object.defineProperty(target, key, {
    get: createComputedGetter(key),
    set: setter
  })
}

function createComputedGetter(key) {
  return function () {
    // this 就是vm,  _computedWatchers是initComputed放进去的
    let watcher = this._computedWatchers[key]
    // 第一次取值的时候是true, 所以会执行计算
    if (watcher.dirty) {
      watcher.evaluate() // 取完值这个方法会把dirty改成 false
    }

    // 让watcher记住dep，再返过来记住watcher
    if (Dep.target) {
      watcher.depend()
    }
    return watcher.value
  }
}
